home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 3
/
Cream of the Crop 3.iso
/
comm
/
wnos5src.zip
/
DOMCLI.C
< prev
next >
Wrap
Text File
|
1993-11-20
|
15KB
|
606 lines
#include <ctype.h>
#include <io.h>
#include <dos.h>
#include "global.h"
#include "config.h"
#include "domain.h"
#include "socket.h"
#include "netuser.h"
#include "files.h"
#include "cmdparse.h"
#include "ip.h" /* for use with autoping entries */
struct dserver *Dlist = NULLDOM;
#ifdef ENH
static struct rr *Rrlist[NRLIST];
#endif
int Dhaveaa = 1;
int DBloaded = 0;
int Db_initialize = 0;
int DTranslate = 0;
int DVerbose = 1;
int Cwrite = 0;
int16 Dcache_size = 20;
static int16 Dtimeout = 60;
int16 Dretries = 1;
char *Dsuffix = NULLCHAR;
int Dstypes[] = {
TYPE_SOA,
TYPE_NS,
TYPE_MX,
TYPE_MD,
TYPE_MF,
TYPE_CNAME,
TYPE_PTR,
TYPE_A,
TYPE_MB,
TYPE_MG,
TYPE_MR,
TYPE_NULL,
TYPE_WKS,
TYPE_HINFO,
TYPE_MINFO,
TYPE_TXT,
0
};
/*----------------------------------------------------------------------*
* list the cache entries *
*-----------------------------------------------------------------------*/
int
docachelist(int argc,char **argv,void *p)
{
int i;
Cache *cap = cache;
static char *Apstates[] = {
"",
"Bad",
"Suspect",
"Good",
"Active",
"Idle"
};
tputs("Address Status Route Setping Name\n");
for (i = 0; i < Dcache_size; i++) {
if(i == Dcache_size) {
break;
}
if(cap->ti) {
char buf[20];
sprintf(buf,"%u.%u.%u.%u", /* always print the ip-address */
hibyte(hiword(cap->address)), /* even if DTranslate is set */
lobyte(hiword(cap->address)),
hibyte(loword(cap->address)),
lobyte(loword(cap->address)));
tprintf("%-17s%-8s%-8s%-8s%s\n",
buf,
cap->type ? "Invalid" : "Valid",
Apstates[cap->state],
Apstates[cap->proc_run],
cap->name);
}
cap++;
}
return 0;
}
static int
docachegarb(int argc,char **argv,void *p)
{
int i;
Cache *cap = cache;
semwait(&Cwrite,1);
for(i = 0; i < Dcache_size; i++) {
if(cap->type == Missing || cap->address == 0) {
cap->ti = 0;
memset(cap->name,0,5);
}
cap++;
}
semrel(&Cwrite);
return 0;
}
/*----------------------------------------------------------------------*
* change the cache size
*-----------------------------------------------------------------------*/
static int
docachesize(int argc,char **argv,void *p)
{
int16 result = 0, newsize = Dcache_size;
if((result = setintrc(&newsize,"DOM cache size",argc,argv,2,50)) == 0) {
if(argc > 1 && newsize > 0){
semwait(&Cwrite,1); /* lock again */
Dcache_size = newsize;
xfree(cache);
cache = cxallocw(sizeof(Cache),(newsize + 2));
semrel(&Cwrite);
}
}
return (int)result;
}
static int
doadds(int argc,char **argv,void *p)
{
struct dserver *dp;
int32 address;
if((address = resolve(argv[1])) == 0) {
tprintf(Badhost,argv[1]);
return 1;
}
if(address == Ip_addr) {
tputs("Use: start domain\n");
return 1;
}
for(dp = Dlist; dp != NULLDOM; dp = dp->next) {
if(dp->address == address) {
break;
}
}
if(dp == NULLDOM) {
dp = mxallocw(sizeof(struct dserver));
dp->address = address;
dp->next = Dlist;
Dlist = dp;
}
/* Pick a wait time for response: it takes about 15 sec on my AT
* to scan trough the domain.txt file. Taking 3 scans (max)
* and giving a little strech to the channel i come to 60 secs */
dp->srtt = dp->timeout = (argc < 3) ? Dtimeout * 1000L : atoi(argv[2]) * 1000L;
dp->mdev = 0;
Dhaveaa = 0; /* another is also responsible */
return 0;
}
static int
dodfile(int argc,char **argv,void *p)
{
if(argc < 2) {
if(Dfile != NULLCHAR) {
tprintf("%s\n",Dfile);
}
} else {
if(access(argv[1],0) == 0) {
xfree(Dfile);
Dfile = strxdup(argv[1]);
} else {
tputs("No such domain file\n");
return -1;
}
}
return 0;
}
static int
dodropds(int argc,char **argv,void *p)
{
struct dserver *dp, *dptmp = NULLDOM;
int32 addr;
if((addr = resolve(argv[1])) == 0) {
tprintf(Badhost,argv[1]);
} else {
for(dp = Dlist; dp != NULLDOM; dptmp = dp, dp = dp->next) {
if(dp->address == addr) {
if(dptmp != NULLDOM) {
dptmp->next = dp->next;
} else {
Dlist = dp->next;
}
xfree(dp);
if(Dlist == NULLDOM) {
Dhaveaa = 1;
}
return 0;
}
}
}
return -1;
}
static int
dolistds(int argc,char **argv,void *p)
{
struct dserver *dp;
tputs("Server srtt mdev timeout queries responses timeouts\n");
for(dp = Dlist; dp != NULLDOM; dp = dp->next) {
tprintf("%-17s%-8lu%-8lu%-8lu%-8lu%-10lu%-8lu\n",
inet_ntoa(dp->address),
dp->srtt,dp->mdev,dp->timeout,
dp->queries,dp->responses,dp->missers);
}
return 0;
}
#ifdef ENH
static int
doload(int argc,char **argv,void *p)
{
FILE *dbase;
int type, numbscan = 0, numbload = 0;
long rrsize = 0;
struct rr *rrp, *rrl, *db_SOA;
struct rr_memory *memory;
char *arg[2];
char Recload[] = "Number of %srecords scanned %d loaded %d\n";
arg[0] = NULLCHAR;
arg[2] = NULLCHAR;
if((dbase = Fopen((argc < 3) ? Dfile : argv[1],READ_TEXT,0,1)) == NULLFILE) {
return 1;
}
memory = mxallocw(sizeof(struct rr_memory));
db_SOA = NULLRR;
if(Lorigin == NULLDLIST) {
Lorigin = mxallocw(sizeof(struct dlist));
Lorigin->name = ""; /* start with empty domain name */
Db_initialize = 1;
while((rrp = get_rr(dbase,memory)) != NULLRR) {
type = rrp->type;
numbscan++;
numbload++;
rrsize += (long)rrp->rdlength;
if(type == TYPE_SOA) {
db_SOA = rrp; /* save for reference */
} else {
rrp->soarec = db_SOA;
}
if(Rrlist[type] == NULLRR) {
Rrlist[type] = rrp; /* initialize linked list */
Rrlistl[type] = rrp;
} else {
Rrlistl[type]->next = rrp;
Rrlistl[type] = rrp; /* append to linked list */
}
}
/* Lorigin stayes as a list of loaded domain origin names.
* it is refered to in rrp->origins loaded in memory.
* having a common origin saves significantly in used
* memory oposed to giving every record a copy of that
* origin. Domain save will reconstruct $origin statements.
*/
tprintf(Recload,"",numbscan,numbload);
tprintf("Memory record size %d extra %ld\n",sizeof(struct rr),rrsize);
Db_initialize = 0;
Dorigin = NULLCHAR; /* not loading anymore */
DBloaded = 1; /* disable domain file access */
} else {
Db_initialize = 1;
while((rrp = get_rr(dbase,memory)) != NULLRR) {
numbscan++;
type = rrp->type;
if(type == TYPE_SOA) {
db_SOA = rrp; /* save for reference */
} else {
rrp->soarec = db_SOA;
}
if(add_rr(NULLFILE,rrp)) {
free_rr(rrp);
} else {
numbload++;
}
}
tprintf(Recload,"additional ",numbscan,numbload);
Db_initialize = 0;
Dorigin = NULLCHAR; /* not loading anymore */
Fclose(dbase);
xfree(memory);
return 0;
}
Fclose(dbase);
xfree(memory->dorigin);
xfree(memory);
if((rrp = Rrlist[TYPE_NS]) != NULLRR) {
rrl = rrp;
while(rrl != NULLRR) {
arg[1] = rrl->rdata.name;
doadds(2,arg,p);
rrl = rrl->next;
}
}
return 0;
}
#endif
#ifdef ENH
static int
donslookup(int argc,char **argv,void *p)
{
int i, len, type = 0;
int16 flags = DOM_DORECURSE | DOM_CANRECURSE; /* Recursion desired */
int32 address;
char *buf;
struct dhdr *dhdr;
struct mbuf *bp;
if((address = resolve(argv[1])) == 0) {
tprintf(Badhost,argv[1]);
return 1;
}
if(isdigit(*argv[2])) {
type = atoi(argv[2]);
if(type > 255) {
type = 0;
}
} else {
for(i = 0; i < NRLIST; i++) {
if(stricmp(argv[2],type2str(i)) == 0) {
type = i;
break;
}
}
}
if(type == 0) {
tprintf("Unknown record type %s\n",argv[2]);
return 1;
}
dhdr = bld_dhdr(QUERY,QUERY,flags,NO_ERROR,argv[3],CLASS_IN,type);
buf = mxallocw(512);
len = res_mkbuf(dhdr,buf,512);
free_dhdr(dhdr);
for(;;) {
if(sendquery(address,buf,len,&bp,Dtimeout * 1000) > 0) {
dhdr = mxallocw(sizeof(struct dhdr));
ntohdomain(dhdr,&bp);
proc_answer(dhdr,NULLDOM,NULLFILE);
free_dhdr(dhdr);
tputs("NS lookup: host added\n");
} else {
tputs("NS lookup: timeout\n");
}
break;
}
return 0;
}
#endif
static int
doretries(int argc,char **argv,void *p)
{
return setintrc(&Dretries,"DOM retries",argc,argv,1,10);
}
#ifdef ENH
static int
dosave(argc,argv,pp)
int argc;
char *argv[];
void *pp;
{
FILE *dbase;
int i, j;
struct rr *rrp;
struct dlist *llist;
char *p;
if((dbase = Fopen((argc < 3) ? "/domain.new" : argv[1],WRITE_TEXT,0,1)) == NULLFILE)
return 1;
if((llist = Lorigin) != NULLDLIST) {
while(llist != NULLDLIST) {
fprintf(dbase,"$origin\t%s\n",llist->name);
for(i = 0, j = Dstypes[i]; (j = Dstypes[i]) != 0; i++) {
if((rrp = Rrlist[j]) != NULLRR) {
while(rrp != NULLRR) {
if((*llist->name == '\0')
&& (rrp->origin == NULLCHAR)) {
if(rrp->type != TYPE_A)
put_rr(dbase,rrp,0);
else if(rrp->rdata.addr != 0) put_rr(dbase,rrp,0);
} else if(rrp->origin == llist->name) {
if(rrp->type != TYPE_A)
put_rr(dbase,rrp,0);
else
if( rrp->rdata.addr != 0)
put_rr(dbase,rrp,0);
}
rrp = rrp->next;
}
}
}
llist = llist->next;
}
} else for(i = 0, j = Dstypes[i]; (j = Dstypes[i]) != 0; i++) {
p = NULLCHAR;
if((rrp = Rrlist[j]) != NULLRR) {
while(rrp != NULLRR) {
if(rrp->name[strlen(rrp->name) - 1] != '.') {
if(p == NULLCHAR && rrp->origin != NULLCHAR)
fprintf(dbase,"$origin %s\n",rrp->origin);
if(p != NULLCHAR && rrp->origin == NULLCHAR)
fputs("$origin \n",dbase);
if(p != NULLCHAR && rrp->origin != NULLCHAR)
if(stricmp(p,rrp->origin))
fprintf(dbase,"$origin %s\n",rrp->origin);
p = rrp->origin;
}
if(rrp->type != TYPE_A)
put_rr(dbase,rrp,0);
else
if( rrp->rdata.addr != 0)
put_rr(dbase,rrp,0);
rrp = rrp->next;
}
}
}
fclose(dbase);
return 0;
}
#endif
static int
dosuffix(int argc,char **argv,void *p)
{
if(argc < 2){
if(Dsuffix != NULLCHAR) {
tprintf("%s\n",Dsuffix);
}
} else {
if(strcmp(argv[1],"none") == 0) {
xfree(Dsuffix);
Dsuffix = NULLCHAR; /* clear out suffix */
} else {
int i = strlen(argv[1]) - 1;
xfree(Dsuffix);
Dsuffix = mxallocw(i + 3);
strcpy(Dsuffix,argv[1]);
if(argv[1][i] != '.') {
strcat(Dsuffix,".");
}
}
}
return 0;
}
static int
dotimeout(int argc,char **argv,void *p)
{
return setintrc(&Dtimeout,"DOM timeout",argc,argv,15,600);
}
static int
dotranslate(int argc,char **argv,void *p)
{
return setbool(&DTranslate,"DOM translate",argc,argv);
}
static int
doverbose(int argc,char **argv,void *p)
{
return setbool(&DVerbose,"DOM verbose",argc,argv);
}
#ifdef ENH
static int
dozoneinit(int argc,char **argv,void *p)
{
struct dhdr *dhdr;
struct dserver *dp;
struct sockaddr_in server;
int32 address;
int16 flags;
char *buf, *bootname, *domainname, *name = argv[1];
int len, s, resp;
struct mbuf *bp;
FILE *fp;
if(*name == '[') {
address = aton(name+1);
} else {
if(isaddr(name)) {
address = aton(name);
} else {
tprintf("Can't resolve %s currently\n",argv[1]);
return 1;
}
}
dp = mxallocw(sizeof(struct dserver));
dp->srtt = dp->timeout = Dtimeout * 1000;
dp->mdev = 0;
DBloaded = 1; /* disable domain file access */
bootname = (argc > 2) ? argv[2] : "/domain.txt";
domainname = (argc > 3) ? argv[3] : "/domain.new";
/* do zoneinit from remote server */
server.sin_family = AF_INET;
server.sin_port = IPPORT_DOMAIN;
server.sin_addr.s_addr = address;
flags = DOM_DORECURSE | DOM_CANRECURSE; /* Recursion desired */
buf = mxallocw(512);
dhdr = bld_dhdr(QUERY,ZONEINIT,flags,NO_ERROR,bootname,CLASS_IN,TYPE_ANY);
len = res_mkbuf(dhdr,buf,512);
bp = qdata(buf,(int16)len);
if((fp = Fopen(domainname,WRITE_TEXT,0,1)) != NULLFILE) {
if((s = socket(AF_INET,SOCK_DGRAM,0)) != -1) {
send_mbuf(s,bp,0,(char *)&server,SOCKSIZE);
for(;;) {
alarm(dp->timeout);
resp = recv_mbuf(s,&bp,0,NULLCHAR,0);
alarm(0L);
if(resp == -1) {
break;
}
ntohdomain(dhdr,&bp);
proc_answer(dhdr,dp,fp);
}
close_s(s);
}
Fclose(fp);
}
xfree(buf);
free_dhdr(dhdr);
xfree(dp);
DBloaded = 0;
return 0;
}
#endif
static int
docache(int argc,char **argv,void *p)
{
struct cmds Dcachecmds[] = {
"garb", docachegarb, 0, 0, NULLCHAR,
"list", docachelist, 0, 0, NULLCHAR,
"size", docachesize, 0, 0, NULLCHAR,
NULLCHAR,
};
return subcmd(Dcachecmds,argc,argv,p);
}
int
dodomain(int argc,char **argv,void *p)
{
struct cmds Dcmds[] = {
"add", doadds, 0, 2, "domain add <server> [<timeout>]",
"cache", docache, 0, 0, NULLCHAR,
"dfile", dodfile, 0, 0, NULLCHAR,
"drop", dodropds, 0, 2, "domain drop <server>",
"list", dolistds, 0, 0, NULLCHAR,
#ifdef ENH
"load", doload, 0, 0, "domain load [<filename>]",
"nslookup", donslookup, 1024, 4, "domain nslookup <server> <record type> <name>",
#endif
"retries", doretries, 0, 0, NULLCHAR,
#ifdef ENH
"save", dosave, 0, 0, "domain save [<filename>]",
#endif
"suffix", dosuffix, 0, 0, NULLCHAR,
"timeout", dotimeout, 0, 0, NULLCHAR,
"translate",dotranslate,0, 0, NULLCHAR,
"verbose", doverbose, 0, 0, NULLCHAR,
#ifdef ENH
"zoneinit", dozoneinit, 1024, 2, "domain zoneinit <server> [<filename>]",
#endif
NULLCHAR, NULLFP, 0, 0, NULLCHAR,
};
return subcmd(Dcmds,argc,argv,p);
}